#include <math.h>
#include <stdio.h>
#include <stdint.h>

// 快速logf实现 - 基于多项式逼近
// 不含错误处理，请传入正确的数据
// log(0.1): std=-2.302585, fast=-2.302595, error=1.025200e-05 (0.000445%)
// log(0.5): std=-0.693147, fast=-0.693147, error=0.000000e+00 (0.000000%)
// log(1.0): std=0.000000, fast=0.000000, error=0.000000e+00 (nan%)
// log(2.0): std=0.693147, fast=0.693147, error=0.000000e+00 (0.000000%)
// log(5.0): std=1.609438, fast=1.609438, error=1.192093e-07 (0.000007%)
// log(10.0): std=2.302585, fast=2.302585, error=0.000000e+00 (0.000000%)
// log(100.0): std=4.605170, fast=4.605163, error=7.152557e-06 (0.000155%)
// log(1000.0): std=6.907755, fast=6.907642, error=1.134872e-04 (0.001643%)
// log(10000.0): std=9.210340, fast=9.210340, error=0.000000e+00 (0.000000%)
// log(100000.0): std=11.512925, fast=11.512920, error=4.768372e-06 (0.000041%)
float fast_logf_poly(float x) {
    typedef union {
        float f;
        uint32_t u;
    } float_uint;
    float_uint fu = {.f = x};
    
    // 提取指数和尾数
    int32_t exp = ((fu.u >> 23) & 0xFF) - 127;
    float m = 1.0f + (float)(fu.u & 0x7FFFFF) * (1.0f / 8388608.0f); // 1/(2^23)
    
    // z = (m-1)/(m+1)
    float z = (m - 1.0f) / (m + 1.0f);
    float z2 = z * z;
    
    // 5阶多项式系数
    float log_m = z * (2.0f + z2 * (0.6666666f + z2 * 0.4000000f));
    
    return 0.69314718f * exp + log_m; // log(2) ≈ 0.69314718
}

// 标准库版本的温度计算
static float calculate_ntc_temp_std(uint16_t result_ntc) {
    #define ADC_RESOLUTION 4095.0f
    #define R_REF 10000.0f
    #define SH_A 1.1218199445e-03f
    #define SH_B 2.3582428380e-04f  
    #define SH_C 7.7346110381e-08f
    
    float ntc_resistance;
    if (result_ntc > 0) {
        ntc_resistance = R_REF / (ADC_RESOLUTION / (float)result_ntc - 1.0f);
    } else {
        return 500.0f;
    }
    
    float lnR = logf(ntc_resistance);
    float invT = SH_A + SH_B * lnR + SH_C * lnR * lnR * lnR;
    float tempK = 1.0f / invT;
    return tempK - 273.15f;
}

// 快速版本的温度计算
static float calculate_ntc_temp_fast(uint16_t result_ntc) {
    #define ADC_RESOLUTION 4095.0f
    #define R_REF 10000.0f
    #define SH_A 1.1218199445e-03f
    #define SH_B 2.3582428380e-04f  
    #define SH_C 7.7346110381e-08f
    
    float ntc_resistance;
    if (result_ntc > 0) {
        ntc_resistance = R_REF / (ADC_RESOLUTION / (float)result_ntc - 1.0f);
    } else {
        return 500.0f;
    }
    
    float lnR = fast_logf_poly(ntc_resistance);  // 使用快速logf
    float invT = SH_A + SH_B * lnR + SH_C * lnR * lnR * lnR;
    float tempK = 1.0f / invT;
    return tempK - 273.15f;
}

// 测试函数
void test_logf_accuracy() {
    printf("Testing logf accuracy for NTC temperature calculation...\n");
    
    float max_temp_error = 0.0f;
    float max_log_error = 0.0f;
    int error_count = 0;
    int total_tests = 0;
    
    // 测试典型的NTC电阻范围（电阻约100Ω-100kΩ）
    for (uint16_t adc_val = 10; adc_val < 4085; adc_val += 1) {
        total_tests++;
        
        float temp_std = calculate_ntc_temp_std(adc_val);
        float temp_fast = calculate_ntc_temp_fast(adc_val);
        if(adc_val == 10 || adc_val == 4084 || adc_val == 2048){
            printf("adc_val=%d, temp_std=%.5f, temp_fast=%.2f\n", adc_val, temp_std, temp_fast);
        }
        float temp_error = fabsf(temp_std - temp_fast);
        
        if (temp_error > max_temp_error) {
            max_temp_error = temp_error;
        }
        
        // 检查是否超过0.05°C误差
        if (temp_error > 0.05f) {
            error_count++;
            if (error_count <= 10) { // 只打印前10个错误
                float resistance = 10000.0f / (4095.0f / (float)adc_val - 1.0f);
                float lnR_std = logf(resistance);
                float lnR_fast = fast_logf_poly(resistance);
                float log_error = fabsf(lnR_std - lnR_fast);
                
                printf("ADC=%4d, R=%.1fΩ, Temp_std=%.3f°C, Temp_fast=%.3f°C, Error=%.4f°C, Log_error=%.6f\n",
                       adc_val, resistance, temp_std, temp_fast, temp_error, log_error);
            }
        }
    }
    
    printf("\nTest Results:\n");
    printf("Total tests: %d\n", total_tests);
    printf("Max temperature error: %.4f°C\n", max_temp_error);
    printf("Tests with error > 0.05°C: %d\n", error_count);
    
    if (max_temp_error < 0.05f) {
        printf("✓ SUCCESS: All temperature errors are within 0.05°C\n");
    } else {
        printf("✗ FAILURE: Some temperature errors exceed 0.05°C\n");
    }
    
    // 额外测试logf函数本身的精度
    printf("\nLog function accuracy test:\n");
    float test_values[] = {0.1f, 0.5f, 1.0f, 2.0f, 5.0f, 10.0f, 100.0f, 1000.0f, 10000.0f, 100000.0f};
    for (int i = 0; i < 10; i++) {
        float x = test_values[i];
        float log_std = logf(x);
        float log_fast = fast_logf_poly(x);
        float error = fabsf(log_std - log_fast);
        float rel_error = error / fabsf(log_std) * 100.0f;
        printf("log(%.1f): std=%.6f, fast=%.6f, error=%e (%f%%)\n", 
               x, log_std, log_fast, error, rel_error);
    }
}

int main() {
    test_logf_accuracy();
    
    return 0;
}